/**
 * Copyright 2009-2010 rpn4j.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.rpn4j.ctx;

import java.util.HashMap;
import java.util.Map;

import org.rpn4j.calc.Addition;
import org.rpn4j.calc.Division;
import org.rpn4j.calc.Multiplication;
import org.rpn4j.calc.Square;
import org.rpn4j.calc.Substraction;
import org.rpn4j.core.Function;
import org.rpn4j.core.Variable;

/**
 * Implementation of the {@link Context} interface.
 * 
 * <p>
 * Following buildin functions are available at this time:
 * + -> addition
 * - -> substraction
 * * -> multiplication 
 * / -> division
 * sqr -> scare
 * </p>
 * 
 * @author hillger.t
 */
public class RpnContext implements Context {
  private final Map<String, Function> fMapping = new HashMap<String, Function>();
  private final Map<String, Variable> vMapping = new HashMap<String, Variable>();

  private RpnContext() {
    fMapping.put("+", new Addition());
    fMapping.put("-", new Substraction());
    fMapping.put("*", new Multiplication());
    fMapping.put("/", new Division());
    fMapping.put("sqr", new Square());    
  }

  public static Context newInstance() {
    Context context = new RpnContext();
    return context;
  }

  public void register(String key, Variable variable) {
    vMapping.put(key, variable);    
  }

  public void register(String name, Function function) {
    fMapping.put(name, function);
  }

  public Variable findVariable(String name) {
    return vMapping.get(name);
  }

  public Function findFunction(String name) {
    return fMapping.get(name);
  }

  public Types getType(String name) {
    if (vMapping.containsKey(name))
      return Types.VARIABLE;
    else if (fMapping.containsKey(name))
      return Types.FUNCTION;
    else
      return Types.NUMBERIC;
  }
}
